package com.xsky.database.dao.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

import com.xsky.common.util.HibernateUtil;
import com.xsky.database.dao.facade.IBaseEnityDao;

public class BaseEntityDaoImpl implements IBaseEnityDao
{
	public int recordCount(String entityFullName,String condition)
	{
		
		Session hibernateSession;
		String[] conditions = null;
		if(condition != null && !"".equals(condition.trim()))
		{
			conditions = condition.split("and");
		}
		Class entityClass = null;
		try
		{
			entityClass = Class.forName(entityFullName);
		} 
		catch (ClassNotFoundException e)
		{
			e.printStackTrace();
		}
		try
		{
			hibernateSession = HibernateUtil.currentSession();
			hibernateSession.clear();
			Criteria criteria = hibernateSession.createCriteria(entityClass);
			if(conditions != null)
			{
				for(int i = 0; i < conditions.length; i++)
				{
					String type = conditions[i].split("=")[0].trim();
					String value = conditions[i].split("=")[1].trim().replace("'", "");
					criteria.add(Restrictions.eq(type, value));
				}
			}
			return criteria.list().size();
		}
		catch (RuntimeException re)
		{
			System.out.println(re.getMessage());
			throw re;
		}
		finally
		{
			HibernateUtil.closeSession();
		}
	}
	public int fetchCount(String entityFullName,String condition)
	{
		
		Session hibernateSession;
		try
		{
			hibernateSession = HibernateUtil.currentSession();
			hibernateSession.clear();
			if(condition==null||"".equals(condition.trim()))
			{
				Query query = hibernateSession.createQuery("from "+entityFullName+" model");
				return query.list().size();
			}
			else
			{
				Query query = hibernateSession.createQuery("from "+entityFullName+" model where "+condition);
				return query.list().size();
			}
		}
		catch (RuntimeException re)
		{
			re.printStackTrace();
			throw re;
		}
		finally
		{
			HibernateUtil.closeSession();
		}
	}
	public List fetchByPagesWithCondition(String entityFullName, String start, String limit,String condition, String orderBy, String orderType)
	{
		
		List resultList = new ArrayList();
		Session hibernateSession;
		int firstNum = Integer.parseInt(start);
		int limitNum = Integer.parseInt(limit);
		try
		{
			hibernateSession = HibernateUtil.currentSession();
			hibernateSession.clear();
			Query query = null;
			String hql = "";
			if(condition==null||"".equals(condition.trim()))
			{
				hql = "from "+entityFullName+" model";
			}
			else
			{
				hql = "from "+entityFullName+" model where "+condition;
			}
			if(orderBy != null && !"".equals(orderBy.trim()))
			{
				if("asc".equals(orderType))
				{
					hql = hql + " order by "+orderBy+" asc";
				}
				else
				{
					hql = hql + " order by "+orderBy+" desc";
				}
			}
			query = hibernateSession.createQuery(hql);
			query.setFirstResult(firstNum-1);
			query.setMaxResults(limitNum);
			resultList = query.list();
			
		}
		catch (RuntimeException re)
		{
			System.out.println(re.getMessage());
			throw re;
		}
		finally
		{
			HibernateUtil.closeSession();
		}
		return resultList;
	}
	public List findByPagesWithCondition(String entityFullName, String start, String limit,String condition, String orderBy, String orderType)
	{
		
		List resultList = new ArrayList();
		int pageSize = Integer.parseInt(limit);
		Session hibernateSession;
		String[] conditions = null;
		if(condition != null && !"".equals(condition.trim()))
		{
			conditions = condition.split("and");
		}
		Class entityClass = null;
		try
		{
			entityClass = Class.forName(entityFullName);
		} 
		catch (ClassNotFoundException e)
		{
			e.printStackTrace();
		}
		int firstNum = Integer.parseInt(start);
		try
		{
			hibernateSession = HibernateUtil.currentSession();
			hibernateSession.clear();
			Criteria criteria = hibernateSession.createCriteria(entityClass);
			if(conditions != null)
			{
				for(int i = 0; i < conditions.length; i++)
				{
					String type = conditions[i].split("=")[0].trim();
					String value = conditions[i].split("=")[1].trim().replace("'", "");
					criteria.add(Restrictions.eq(type, value));
				}
			}
			
			if(orderBy != null && !"".equals(orderBy.trim()))
			{
				if("asc".equals(orderType))
				{
					criteria.addOrder(Order.asc(orderBy));
				}
				else
				{
					criteria.addOrder(Order.desc(orderBy));
				}
			}
			criteria.setFirstResult(firstNum);
			criteria.setMaxResults(pageSize);
			resultList = criteria.list();
			
		}
		catch (RuntimeException re)
		{
			re.printStackTrace();
			throw re;
		}
		finally
		{
			HibernateUtil.closeSession();
		}
		return resultList;
	}
	public List findByHql(String hql)
	{
		List resultList = new ArrayList();
		Session session = HibernateUtil.currentSession();
		try
		{
			Query queryObject = session.createQuery(hql);
			resultList = queryObject.list();
			
		}
		catch (RuntimeException re)
		{
			re.printStackTrace();
			throw re;
		}
		finally
		{
			HibernateUtil.closeSession();
		}
		
		return resultList;
	}
	public void deleteByHql(String hql)
	{
		Session session = HibernateUtil.currentSession();
		try
		{
			Query queryObject = session.createQuery(hql);
			Transaction ts = session.beginTransaction();
			queryObject.executeUpdate();
			ts.commit();
		}
		catch (RuntimeException re)
		{
			throw re;
		}
		finally
		{
			HibernateUtil.closeSession();
		}
	}
	/**
	 * 
	 * 执行HQL语句，通常是更新、删除等不需要返回值的操作
	 * @param hql HQL语句
	 */
	public void execute(String hql)
	{
		Session session = HibernateUtil.currentSession();
		try
		{
			Query queryObject = session.createQuery(hql);
			Transaction ts = session.beginTransaction();
			queryObject.executeUpdate();
			ts.commit();
		}
		catch (RuntimeException re)
		{
			throw re;
		}
		finally
		{
			HibernateUtil.closeSession();
		}
	}
	/**
	 * 
	 * 分页查询
	 * @param entityFullName 实体的全路径名
	 * @param start 开始的记录数
	 * @param limit最多可以取的记录的条数
	 * @param orderBy 排序采用的字段的名称
	 * @param orderType 排序类型 desc 或� asc
	 * @return 返回结果集实体列表
	 */
	public List findByPages(String entityFullName, String start, String limit, String orderBy, String orderType)
	{
		
		List resultList = new ArrayList();
		int pageSize = Integer.parseInt(limit);
		Session hibernateSession;
		Class entityClass = null;
		try
		{
			entityClass = Class.forName(entityFullName);
		} catch (ClassNotFoundException e)
		{
			e.printStackTrace();
		}
		int firstNum = Integer.parseInt(start);
		try
		{
			hibernateSession = HibernateUtil.currentSession();
			Criteria criteria = hibernateSession.createCriteria(entityClass);
			if(orderBy != null && !"".equals(orderBy.trim()))
			{
				if("asc".equals(orderType))
				{
					criteria.addOrder(Order.asc(orderBy));
				}
				else
				{
					criteria.addOrder(Order.desc(orderBy));
				}
			}
			criteria.setFirstResult(firstNum);
			criteria.setMaxResults(pageSize);
			resultList = criteria.list();
			
		}
		catch (RuntimeException re)
		{
			throw re;
		}
		finally
		{
			HibernateUtil.closeSession();
		}
		return resultList;
	}
	public void saveOrUpdateEntity(Object entity) 
	{
			Session session;
			try
			{
				
				session = HibernateUtil.currentSession();
				Transaction ts = session.beginTransaction();
				session.saveOrUpdate(entity);
				ts.commit();
			}
			catch (RuntimeException re)
			{
				throw re;
			}
			 finally
	         {
				 HibernateUtil.closeSession();
	         }
			
	}
	/**
	 * @param persistentInstance 
	 * 实体
	 */
	public void delete(Object persistentInstance)
	{
		Session session;
        Transaction ts = null;
		try
		{
			session = HibernateUtil.currentSession();
            ts = session.beginTransaction();
            session.delete(persistentInstance);
			ts.commit();
		}
		catch (RuntimeException re)
		{
			throw re;
		}
		 finally
         {
			 HibernateUtil.closeSession();
         }
	}
	
	/**
	 * 
	 * 通过传入的Map从数据库中删除记录<br>
	 * @param map 
	 * hql语言哈希表
	 * <p>
	 * 	对map中的值有几点说明:<br>
	 * 	1、key为tableEntity 时代表要删除的实体类：例如：有com.xsky.Student实体，则map.put("tableEntity","com.xsky.Student");
	 * 		<br>&nbsp;&nbsp;或者map.put("tableEntity","Student");<br>
	 * 	2、剩下的就根据实际情况添加限制字段，例如Student类有 name属性，想要删除 name="congpy"的学生，则可以map.put("name","congpy");
	 * </p>
	 */
	public void deleteByMap(Map map)
	{
		Session session;
        Transaction ts = null;
        String deleteHql = "";
        String tableEntity = (String)map.get("tableEntity");
        deleteHql = "delete "+tableEntity;
        map.remove("tableEntity");
        
		Set keySet = map.keySet();
		String key="";
		String value="";
		for(int i=0; i<keySet.size();i++)
		{
			key = keySet.toArray()[i].toString();
			value = map.get(key).toString();
			if(i==0)
			{
				deleteHql = deleteHql + " where "+ key + "= '" + value +"'";
			}
			else
			{
				deleteHql = deleteHql + " and "+ key + "= '" + value +"'";
			}
		}
		session = HibernateUtil.currentSession();
		ts= session.beginTransaction();
		Query query = session.createQuery(deleteHql);
		query.executeUpdate();
		ts.commit();
		HibernateUtil.closeSession();
	}

	/**
	 * 
	 * 通过某字段从数据库中删除记录<br>
	 * @param entityName 
	 * 实体名字<br>例如：有com.xsky.Student实体，此参数的实参可以为：com.xsky.Student 或者 Student
	 * @param key 
	 * 某属性名<br>例如：Student有id属性�，则此处可以填id的值 id作为实参传入
	 * @param value 
	 * 对应key属�性�，此处传入其实际�值<br>例如:001
	 */
	public void deleteByKey(String entityName, String key, String value)
	{
		Session session;
        Transaction ts = null;
        String deleteHql = "";
        deleteHql = "delete "+ entityName +" where "+ key + "='"+value+"'";
		session = HibernateUtil.currentSession();
		ts= session.beginTransaction();
		Query query = session.createQuery(deleteHql);
		query.executeUpdate();
		ts.commit();
		HibernateUtil.closeSession();
	}

	/**
	 * 向数据库中插入一个实体
	 */
	public void insertEntity(Object entity)
	{
		Session session;
        Transaction ts = null;
        try
            {
                session = HibernateUtil.currentSession();
                ts = session.beginTransaction();
                session.save(entity);
                ts.commit();
            } catch (HibernateException e)
            {
               e.printStackTrace();
                if (ts != null)
                    {
                        ts.rollback();
                    }
            } finally
            {
            	HibernateUtil.closeSession();
            }
	}

	/**
	 * 向数据库中插入List列表上的实体
	 */
	public void insertEntity(List entities)
	{
		Session session;
        Transaction ts = null;
        try
            {
        	Object entity = null;
			session = HibernateUtil.currentSession();
			ts = session.beginTransaction();
			for(int i = 0; i < entities.size(); i++)
			{
				entity = entities.get(i);
				 session.save(entity);
			}
                ts.commit();
            } catch (HibernateException e)
            {
                System.out.println(e.getMessage());
                if (ts != null)
                    {
                        ts.rollback();
                    }
            } finally
            {
            	HibernateUtil.closeSession();
            }
	}

	/**
	 * 通过 Map进行查询
	 * map中一定要有的键为entity，对应的值为表对应的实体名（为全路径名）
	 */
	public List selectByMap(Map map)
	{
		Session session;
		List recordList = new ArrayList();
        String tableEntity = (String)map.get("entity");
        map.remove("entity");
		session = HibernateUtil.currentSession();
		Criteria criteria = session.createCriteria(tableEntity);
		criteria.add(Restrictions.allEq(map));
		recordList = criteria.list();
		HibernateUtil.closeSession();
		return recordList;
	}
	
	/**
	 * 通过唯一主键查询
	 */
	public Object findByPrimaryKey(Object entity, String key,String value)
	{
		Session session;
		Class cl = entity.getClass();
		String className = cl.getName();
        String hql = "from " + className+" where "+key+"='"+value+"'";
        List resultList = new ArrayList();
		session = HibernateUtil.currentSession();
		Query queryObject = session.createQuery(hql);
		resultList = queryObject.list();
		if(resultList.size()>0)
		{
			entity = resultList.get(0);
		}
		else
		{
			entity = null;
		}
		HibernateUtil.closeSession();
		return entity;
	}
	/**
	 * 通过唯一主键查询
	 */
	public List findByKey(Object entity, String key,String value)
	{
		Session session;
		Class cl = entity.getClass();
		String className = cl.getName();
        String hql = "from " + className+" where "+key+"='"+value+"'";
        List resultList = new ArrayList();
		session = HibernateUtil.currentSession();
		Query queryObject = session.createQuery(hql);
		resultList = queryObject.list();
		HibernateUtil.closeSession();
		return resultList;
	}
	/**
	 * 更新实体对应记录的信息
	 * 更新的是单个实体
	 */
	public void updateEntity(Object entity) 
	{
			Session session;
			try
			{
				
				session = HibernateUtil.currentSession();
				Transaction ts = session.beginTransaction();
				session.update(entity);
				ts.commit();
			}
			catch (RuntimeException re)
			{
				throw re;
			}
			 finally
	         {
				 HibernateUtil.closeSession();
	         }
			
	}

	/**
	 * 更新列表中所有的实体对应的数据库中的记录
	 */
	public void updateEntity(List entities) 
	{
		Session session;
		try
		{
			Object entity = null;
			session = HibernateUtil.currentSession();
			Transaction ts = session.beginTransaction();
			for(int i = 0; i < entities.size(); i++)
			{
				entity = entities.get(i);
				session.update(entity);
			}
			ts.commit();
		}
		catch (RuntimeException re)
		{
			throw re;
		}
		 finally
         {
			 HibernateUtil.closeSession();
         }
		
	}
	
	/**
	 * 根据实体类名
	 * 查询所有的实体
	 */
	public List findAll(String className)
	{
		Session session;
		try
		{
			session = HibernateUtil.currentSession();
			String queryString = "from "+className;
			Query queryObject = session.createQuery(queryString);
			return queryObject.list();
		}
		catch (RuntimeException re)
		{
			throw re;
		}
		finally
        {
			HibernateUtil.closeSession();
        }
	}
}
